﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Linq;

namespace ConfigFile
{
    public class ConfigFile
    {
        private List<string> _keys;
        private string _name = "";
        private List<string> _subkeys;
        private bool active;
        private StreamReader stream;

        public ConfigFile(string filename)
        {
            if (File.Exists(filename))
            {
                this._name = filename;
                this.stream = File.OpenText(this._name);
                if (this.stream != null)
                {
                    this.active = true;
                    this.stream.Close();
                }
            }
        }

        public List<string> Get_Key(string Key)
        {
            if (this.active)
            {
                this.Opencfg();
                List<string> list = new List<string>();
                bool flag = false;
                string str = Key;
                this.stream.BaseStream.Position = 0L;
                this.stream.BaseStream.Flush();
                string source = "";
                while (!this.stream.EndOfStream)
                {
                    source = this.stream.ReadLine().Trim(new char[] { '\t', ' ' });
                    if (((source != "") && (source != null)) && ((source.ElementAt<char>(0) != '#') && (source.ElementAt<char>(0) != '/')))
                    {
                        if (!flag && (source.Trim() == str))
                        {
                            flag = true;
                        }
                        if ((flag && (source != null)) && (source != str))
                        {
                            if ((source.ElementAt<char>(0) != '{') && (source.ElementAt<char>(0) != '}'))
                            {
                                list.Add(source);
                            }
                            else if (source.ElementAt<char>(0) == '}')
                            {
                                break;
                            }
                        }
                    }
                }
                this.stream.Close();
                if (flag && (list.Count > 0))
                {
                    return list;
                }
            }
            return null;
        }

        public List<string> Get_Keys()
        {
            if (this.active)
            {
                if (this._keys != null)
                {
                    return this._keys;
                }
                this.Opencfg();
                List<string> list = new List<string>();
                bool flag = false;
                this.stream.BaseStream.Position = 0L;
                this.stream.BaseStream.Flush();
                while (!this.stream.EndOfStream)
                {
                    string item = this.stream.ReadLine().Trim(new char[] { '\t', ' ' });
                    if (((item != "") && (item.Substring(0, 1) != "#")) && (item.Substring(0, 1) != "/"))
                    {
                        if (((item.Substring(0, 1) != "{") && (item != "")) && (item.Substring(0, 1) != "}"))
                        {
                            string tt = item.Trim();
                            if (!flag && !list.Exists(tk => tk == tt))
                            {
                                list.Add(item);
                                flag = true;
                            }
                        }
                        else if (item.Substring(0, 1) == "}")
                        {
                            flag = false;
                        }
                    }
                }
                this.stream.Close();
                if (list.Count > 0)
                {
                    this._keys = list;
                    return list;
                }
                this._keys = list;
            }
            return null;
        }

        public bool Get_ParamB(string Value, int Index)
        {
            string[] strArray = Value.Split(new char[] { ',' });
            if (Index > strArray.Length)
            {
                return false;
            }
            return (strArray[Index - 1].Trim().ToLower() == "true");
        }

        public int Get_ParamI(string Value, int Index)
        {
            string[] strArray = Value.Split(new char[] { ',' });
            if (Index > strArray.Length)
            {
                return 0;
            }
            return int.Parse(strArray[Index - 1].Trim());
        }

        public string Get_ParamS(string Value, int Index)
        {
            string[] strArray = Value.Split(new char[] { ',' });
            if (Index > strArray.Length)
            {
                return "";
            }
            return strArray[Index - 1];
        }

        public List<string> Get_SubKeys()
        {
            if (this.active)
            {
                if (this._subkeys != null)
                {
                    return this._subkeys;
                }
                List<string> list = new List<string>();
                if (this._keys == null)
                {
                    this.Get_Keys();
                }
                this.Opencfg();
                foreach (string str in this._keys)
                {
                    Predicate<string> match = null;
                    string[] tmp = str.Split(new char[] { '.' });
                    if ((tmp.Length > 1) && (tmp[1] != ""))
                    {
                        if (match == null)
                        {
                            match = tk => tk == tmp[1];
                        }
                        if (!list.Exists(match))
                        {
                            list.Add(tmp[1]);
                        }
                    }
                }
                this.stream.Close();
                if (list.Count > 0)
                {
                    this._subkeys = list;
                    return list;
                }
                this._subkeys = list;
            }
            return null;
        }

        private void Opencfg()
        {
            this.stream = File.OpenText(this._name);
            if (this.stream == null)
            {
                throw new Exception("Error in Configuration file");
            }
        }
    
    }
}
